home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload Trio 2
/
Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO
/
dir38
/
vga_doc2.zip
/
SUPERVGA.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1993-02-02
|
39KB
|
1,548 lines
unit supervga;
interface
uses dos;
type
str10=string[10];
mmods=(_text,
_text2,
_text4,
_pl2 , {plain mono, 8 pixels per byte}
_pl2e, {mono odd/even, 8 pixels per byte, two planes}
_herc, {Hercules mono, 4 "banks" of 8kbytes}
_cga2, {CGA 2 color, 2 "banks" of 16kbytes}
_cga4, {CGA 4 color, 2 "banks" of 16kbytes}
_pl4 , {4 color odd/even planes}
_pk4 , {4 color "packed" pixels 4 pixels per byte}
_pl16, {std EGA/VGA 16 color: 4 planes, 8 pixels per byte}
_pk16, {ATI mode 65h two 16 color pixels per byte}
_p256, {one 256 color pixel per byte}
_p32k, {Sierra 15 bit}
_p64k, {Sierra 16bit/XGA}
_p16m); {RGB 3bytes per pixel}
modetype=record
md,xres,yres,bytes:word;
memmode:mmods;
end;
CHIPS=(__EGA,__VGA,__chips451,__chips452,__chips453,__paradise,__video7
,__tseng3,__tseng4,__tridBR,__tridCS,__trid89,__everex,__ati1,__ati2
,__genoa,__oak,__cirrus,__aheadA,__aheadB,__ncr,__yamaha,__poach
,__s3,__al2101,__acumos,__mxic,__vesa,__realtek,__p2000,__cirrus54
,__none);
const
colbits:array[mmods] of integer=
(0,0,0,1,1,1,1,2,2,2,4,4,8,15,16,24);
modecols:array[mmods] of longint=
(0,0,0,2,2,2,2,4,4,4,16,16,256,32768,65536,16777216);
mdtxt:array[mmods] of string[210]=('Text','2 color Text','4 color Text'
,'Monochrome','2 colors planar','Hercules','CGA 2 color','CGA 4 color'
,'4 colors planar','4 colors packed','16 colors planar','16 colors packed'
,'256 colors packed','32768 colors','65536 colors'
,'16777216 colors');
mmodenames:array[mmods] of string[4]=('TXT ','TXT2','TXT4','PL2 ','PL2E','HERC'
,'CGA2','CGA4','PL4 ','PK4 ','PL16','PK16','P256','P32K','P64K','P16M');
header:array[CHIPS] of string[14]=
('EGA','VGA','Chips&Tech','Chips&Tech','Chips&Tech'
,'Paradise','Video7','ET3000','ET4000'
,'Trident','Trident','Trident','Everex','ATI','ATI'
,'Genoa','Oak','Cirrus','Ahead','Ahead','NCR'
,'Yamaha','Poach','S3','AL2101','Acumos','MXIC'
,'VESA','Realtek','PRIMUS','Cirrus54','');
novgamodes=10;
stdmodetbl:array[1..novgamodes] of modetype=
((md: 4;xres:320;yres:200;bytes: 80;memmode:_cga4)
,(md: 5;xres:320;yres:200;bytes: 80;memmode:_cga4)
,(md: 6;xres:640;yres:200;bytes: 80;memmode:_cga2)
,(md:13;xres:320;yres:200;bytes: 40;memmode:_pl16)
,(md:14;xres:640;yres:200;bytes: 80;memmode:_pl16)
,(md:15;xres:640;yres:350;bytes: 80;memmode:_pl2)
,(md:16;xres:640;yres:350;bytes: 80;memmode:_pl16)
,(md:17;xres:640;yres:480;bytes: 80;memmode:_pl2)
,(md:18;xres:640;yres:480;bytes: 80;memmode:_pl16)
,(md:19;xres:320;yres:200;bytes:320;memmode:_p256));
_dac0 =0; {No DAC (MDA/CGA/EGA ..}
_dac8 =1; {Std VGA DAC 256 cols.}
_dac15 =2; {Sierra 32k DAC}
_dac16 =3; {Sierra 64k DAC}
_dacss24 =4; {Sierra?? 24bit RGB DAC}
_dacatt =5; {ATT 20c491/2 15/16/24 bit DAC}
_dacADAC1 =6; {Acumos ADAC1 15/16/24 bit DAC}
vesa:word=0;
var
rp:registers;
memmode:mmods; {current memory mode}
vseg:word; {Video buffer base segment}
video:string[5];
mm:word; {Video memory in kilobytes}
CHIP:CHIPS;
dacname:string[20];
dactype:word;
crtc:word; {I/O address of CRTC registers}
_crt:string[20];
secondary:string[20];
extra:string[80];
name:string[40];
curmode:word; {Current mode number}
pixels:word; {Pixels in a scanline in current mode}
lins:word; {lines in current mode}
bytes:longint; {bytes in a scanline}
planes:word; {number of video planes}
nomodes:word;
modetbl:array[1..30] of modetype;
vesarec:record
attr:word;
wina,winb:byte;
gran,winsiz,sega,segb:word;
pagefunc:pointer;
bytes,width,height:word;
charw,charh,planes,bits,nbanks,model,banks:byte;
x:array[byte] of byte; {might get trashed by 4F01h}
end;
dotest:array[CHIPS] of boolean;
function strip(s:string):string; {strip leading and trailing spaces}
function upstr(s:string):string; {convert a string to upper case}
function istr(w:longint):str10;
function hex2(w:word):str10;
function hex4(w:word):str10;
procedure vio(ax:word); {INT 10h reg ax=AX. other reg. set from RP
on return rp.ax=reg AX}
function inp(reg:word):byte; {Reads a byte from I/O port REG}
procedure outp(reg,val:word); {Write the low byte of VAL to I/O port REG}
function rdinx(pt,inx:word):word; {read register PT index INX}
procedure wrinx(pt,inx,val:word); {write VAL to register PT index INX}
procedure modinx(pt,inx,mask,nwv:word); {In register PT index INX sets
the bits in MASK as in NWV
the other are left unchanged}
procedure setbank(bank:word);
procedure setvstart(l:longint); {Set the display start address}
function setmode(md:word):boolean;
procedure vesamodeinfo(md:word);
procedure dactocomm;
procedure dactopel;
procedure findvideo;
implementation
const
mmmask :array[0..8] of byte=(0,0,0,0,1,3,3,7,15);
hx:array[0..15] of char='0123456789ABCDEF';
var
atireg:word; {ATI extended registers}
old,curbank:word;
biosseg:word;
vgran:word;
function strip(s:string):string; {strip leading and trailing spaces}
begin
while s[length(s)]=' ' do dec(s[0]);
while copy(s,1,1)=' ' do delete(s,1,1);
strip:=s;
end;
function upstr(s:string):string; {convert a string to upper case}
var x:word;
begin
for x:=1 to length(s) do
s[x]:=upcase(s[x]);
upstr:=s;
end;
function istr(w:longint):str10;
var s:str10;
begin
str(w,s);
istr:=s;
end;
function hex2(w:word):str10;
begin
hex2:=hx[(w shr 4) and 15]+hx[w and 15];
end;
function hex4(w:word):str10;
begin
hex4:=hex2(hi(w))+hex2(lo(w));
end;
procedure vio(ax:word); {INT 10h reg ax=AX. other reg. set from RP
on return rp.ax=reg AX}
begin
rp.ax:=ax;
intr(16,rp);
end;
function inp(reg:word):byte; {Reads a byte from I/O port REG}
begin
reg:=port[reg];
inp:=reg;
end;
procedure outp(reg,val:word); {Write the low byte of VAL to I/O port REG}
begin
port[reg]:=val;
end;
function rdinx(pt,inx:word):word; {read register PT index INX}
var x:word;
begin
if pt=$3C0 then x:=inp($3DA); {If Attribute Register then reset Flip-Flop}
outp(pt,inx);
rdinx:=inp(pt+1);
end;
procedure wrinx(pt,inx,val:word); {write VAL to register PT index INX}
begin
outp(pt,inx);
outp(pt+1,val);
end;
procedure modinx(pt,inx,mask,nwv:word); {In register PT index INX sets
the bits in MASK as in NWV
the other are left unchanged}
var temp:word;
begin
temp:=(rdinx(pt,inx) and not mask)+(nwv and mask);
wrinx(pt,inx,temp);
end;
function getbios(offs,lnn:word):string;
var s:string;
begin
s[0]:=chr(lnn);
move(mem[biosseg:offs],s[1],lnn);
getbios:=s;
end;
function tstrg(pt,msk:word):boolean; {Returns true if the bits in MSK
of register PT are read/writable}
var old,nw1,nw2:word;
begin
old:=inp(pt);
outp(pt,old and not msk);
nw1:=inp(pt) and msk;
outp(pt,old or msk);
nw2:=inp(pt) and msk;
outp(pt,old);
tstrg:=(nw1=0) and (nw2=msk);
end;
function testinx2(pt,rg,msk:word):boolean; {Returns true if the bits in MSK
of register PT index RG are
read/writable}
var old,nw1,nw2:word;
begin
old:=rdinx(pt,rg);
wrinx(pt,rg,old and not msk);
nw1:=rdinx(pt,rg) and msk;
wrinx(pt,rg,old or msk);
nw2:=rdinx(pt,rg) and msk;
wrinx(pt,rg,old);
testinx2:=(nw1=0) and (nw2=msk);
end;
function testinx(pt,rg:word):boolean; {Returns true if all bits of
register PT index RG are
read/writable.}
var old,nw1,nw2:word;
begin
testinx:=testinx2(pt,rg,$ff);
end;
procedure dactopel; {Force DAC back to PEL mode}
begin
if inp($3c8)=0 then;
end;
var
daccomm:word;
procedure dactocomm; {Enter command mode of HiColor DACs}
var x:word;
begin
dactopel;
x:=inp($3c6);
x:=inp($3c6);
x:=inp($3c6);
daccomm:=inp($3c6);
end;
(* Set memory bank *)
procedure setbank(bank:word);
var x:word;
begin
vseg:=$a000;
if bank=curbank then exit; {Only set bank if diff. from current value}
case chip of
__acumos:modinx($3ce,9,$f0,bank shl 4);
__aheadA:begin
wrinx($3ce,13,bank shr 1);
x:=inp($3cc) and $df;
if odd(bank) then inc(x,32);
outp($3c2,x);
end;
__aheadB:wrinx($3ce,13,bank*17);
__al2101:outp($3d7,bank);
__ati1:modinx(atireg,$b2,$1e,bank shl 1);
__ati2:modinx(atireg,$b2,$ee,bank*$22);
__chips451:wrinx(crtc+2,11,bank);
__chips452:wrinx(crtc+2,16,bank shl 2);
__chips453:wrinx(crtc+2,16,bank shl 4);
__everex:begin
x:=inp($3cc) and $df;
if (bank and 2)>0 then inc(x,32);
outp($3c2,x);
modinx($3c4,8,$80,bank shl 7);
end;
__genoa:wrinx($3c4,6,bank*9+64);
__mxic:wrinx($3c4,$c5,bank*17);
__ncr:begin
if memmode<=_pl16 then bank:=bank shl 2;
wrinx($3c4,$18,bank shl 2);
end;
__oak:wrinx($3de,17,bank*17);
__paradise:wrinx($3ce,9,bank shl 4);
__p2000,
__realtek:begin
outp($3d6,bank);
outp($3d7,bank);
end;
__s3:begin
wrinx(crtc,$38,$48);
modinx(crtc,$31,9,9);
if memmode=_pl16 then bank:=bank*4;
modinx(crtc,$35,$f,bank);
wrinx(crtc,$38,0);
end;
__tridBR:;
__tridCS,__poach,__trid89
:begin
wrinx($3c4,11,0);
if rdinx($3c4,11)=0 then;
modinx($3c4,14,$f,bank xor 2);
end;
__tseng3:outp($3cd,bank*9+64);
__tseng4:outp($3cd,bank*17);
__video7:begin
x:=inp($3cc) and $df;
if (bank and 2)>0 then inc(x,32);
outp($3c2,x);
modinx($3c4,$f9,1,bank);
modinx($3c4,$f6,$80,(bank shr 2)*5);
end;
__cirrus54:wrinx($3CE,9,bank*16);
__vesa:begin
rp.bx:=0;
rp.dx:=bank*longint(64) div vgran;
vio($4f05);
rp.bx:=1;
vio($4f05);
end;
end;
curbank:=bank;
end;
procedure vesamodeinfo(md:word);
begin
rp.cx:=md;
rp.es:=seg(vesarec);
rp.di:=ofs(vesarec);
vio($4f01);
vgran:=vesarec.gran;
bytes:=vesarec.bytes;
pixels:=vesarec.width;
lins:=vesarec.height;
case vesarec.bits of
4:memmode:=_pl16;
8:memmode:=_p256;
15:memmode:=_p32k;
16:memmode:=_p64k;
24:memmode:=_p16m;
end;
end;
function safemode(md:word):boolean;
var x,y:word;
begin {Checks if we entered a Graph. mode}
vio(3);
vio(lo(md));
y:=rdinx($3ce,6);
safemode:=odd(y);
end;
function tsvio(ax,bx:word):boolean; {Tseng 4000 Hicolor mode set}
begin
rp.bx:=bx;
vio(ax);
tsvio:=rp.ax=16;
end;
function setmode(md:word):boolean;
var x:word;
begin
setmode:=true;
curmode:=md;
case chip of
__ati1,__ati2:begin
rp.bx:=$5506;
rp.bp:=$ffff;
rp.si:=0;
vio($1200+md);
if rp.bp=$ffff then setmode:=false
else vio(md);
end;
__chips451:begin
setmode:=safemode(md);
x:=inp($46e8);
outp($46e8,x or 16);
outp($103,inp($103) or $80);
outp($46e8,x and $ef);
modinx(crtc+2,4,4,4);
modinx(crtc+2,11,3,1);
end;
__chips452,__chips453:
begin
setmode:=safemode(md);
x:=inp($46e8);
outp($46e8,x or 16);
outp($103,inp($103) or $80);
outp($46e8,x and $ef);
modinx(crtc+2,4,4,4);
modinx(crtc+2,11,3,1);
wrinx(crtc+2,12,0);
end;
__everex:begin
rp.bl:=md;
vio($70);
end;
__paradise:begin
setmode:=safemode(md);
modinx($3ce,15,$17,5);
wrinx(crtc,$29,$85);
modinx($3ce,$b,8,0);
modinx(crtc,$2f,$62,0);
end;
__ncr:begin
setmode:=safemode(md);
wrinx($3c4,5,5);
wrinx($3c4,$18,0);
wrinx($3c4,$19,0);
wrinx($3c4,$1a,0);
wrinx($3c4,$1b,0);
modinx($3c4,$1e,$1c,$18);
end;
__video7:begin
rp.bl:=md;
vio($6f05);
end;
__mxic:begin
setmode:=safemode(md);
wrinx($3c4,$a7,$87); {enable extensions}
end;
__vesa:begin
rp.bx:=md;
vio($4f02);
if rp.ax<>$4f then setmode:=false
else begin
vesamodeinfo(md);
chip:=__vesa;
end;
end;
__acumos:begin
vio(md);
wrinx($3c4,6,$12);
end;
__tseng3:begin
vio(md);
modinx($3c4,4,2,2);
end;
__tseng4:case hi(md) of
0:setmode:=safemode(md);
1:if tsvio($10e0,lo(md)) then
begin
{Diamond SpeedStar 24 does not clear memory}
for x:=0 to 15 do {clear memory}
begin
setbank(x);
mem[$a000:0]:=0;
fillchar(mem[$a000:1],65535,0);
end;
end else setmode:=false;
2:if tsvio($10f0,md shl 8+$ff) then
begin
outp($3bf,3);
outp(crtc+4,$a0); {enable Tseng 4000 Extensions}
wrinx(crtc,$13,0);
modinx(crtc,$3f,$80,$80);
{ outp(crtc+4,$29);
outp($3bf,1); do we need these ? }
wrinx(crtc,$13,0);
modinx(crtc,$3f,$80,$80);
end else setmode:=false;
3:if not tsvio($10f0,lo(md)) then setmode:=false;
4:if tsvio($10f0,lo(md)) then
begin
dactocomm;
x:=inp($3c6);
outp($3c6,x or 64); {set DAC to 64K colors}
dactopel;
end else setmode:=false;
end;
__s3:if md<$100 then setmode:=safemode(md)
else begin
rp.bx:=md;
vio($4f02);
if rp.ax=$4f then
begin
if md<$200 then vesamodeinfo(md);
end
else setmode:=false;
end;
__p2000:begin
setmode:=safemode(md);
if memmode=_p64k then
begin
dactocomm;
outp($3c6,$c0);
end;
(* if memmode=_p16m then
begin {This can trick a ATT20c492 into 24bit mode}
dactocomm;
outp($3c6,$e0);
bytes:=1600;
pixels:=530;
end; *)
end;
else setmode:=safemode(md)
end;
curbank:=$ffff; {Set curbank invalid }
case memmode of
_pl2e,_pl4:planes:=2;
_pl16:planes:=4;
else planes:=1;
end;
for x:=1 to mm div 64 do
begin
setbank(x-1);
mem[$a000:$ffff]:=0;
fillchar(mem[$a000:0],$ffff,0);
end;
modinx($3c4,4,2,2); {Set "more than 64K" flag}
vseg:=$a000;
end;
procedure checkmem(mx:word);
var
fail:boolean;
ma:array[0..99] of byte;
x:word;
begin
memmode:=_p256;
fail:=true;
while (mx>1) and fail do
begin
setbank(mx-1);
move(mem[$a000:0],ma,100);
for x:=0 to 99 do
mem[$a000:x]:=ma[x] xor $aa;
setbank(mx-1);
fail:=false;
for x:=0 to 99 do
if mem[$a000:x]<>ma[x] xor $aa then fail:=true;
move(ma,mem[$a000:0],100);
if not fail then
begin
setbank((mx shr 1)-1);
for x:=0 to 99 do
mem[$a000:x]:=ma[x] xor $55;
setbank(mx-1);
fail:=true;
for x:=0 to 99 do
if mem[$a000:x]<>ma[x] xor $55 then fail:=false;
move(ma,mem[$a000:0],100);
end;
mx:=mx shr 1;
end;
mm:=mx*128;
end;
procedure setvstart(l:longint); {Set the display start address}
var x,y:word;
begin
if chip<>__vesa then
begin
x:=l shr 2;
y:=(l shr 18) and (pred(mm) shr 8); {Mask out any "too" high bits}
wrinx(crtc,13,lo(x));
wrinx(crtc,12,hi(x));
end;
case chip of
__tseng3:modinx(crtc,$23,2,y shl 1);
__tseng4:modinx(crtc,$33,3,y);
__tridcs:modinx(crtc,$1e,32,y shl 5);
__trid89:begin
modinx(crtc,$1e,$a0,y shl 5+128);
wrinx($3c4,11,0);
modinx($3c4,$e,1,y shr 1);
end;
__video7:modinx($3c4,$f6,$70,(y shl 4) and $30);
__paradise:modinx($3ce,$d,$18,y shl 3);
__chips452,__chips453:
begin
wrinx($3d6,12,y);
modinx($3d6,4,4,4);
end;
__ncr:begin
modinx(crtc,$31,$f,y);
end;
__ati1:modinx(atireg,$b0,$40,y shl 6);
__ati2:modinx(atireg,$b0,$c0,y shl 6);
__aheadb:modinx($3ce,$1c,3,y);
__vesa:begin
rp.bx:=0;
rp.cx:=l mod 320;
rp.dx:=l div 320;
vio($4f07);
if rp.ax=0 then;
end;
__s3:begin
wrinx(crtc,$38,$48);
modinx(crtc,$31,$30,y shl 4);
wrinx(crtc,$38,0);
end;
__cirrus54:begin
if y>1 then inc(y,2);
modinx(crtc,$1b,5,y);
end;
__p2000:modinx($3ce,$21,$7,y);
end;
end;
procedure UNK(chp:string;id:word);
begin
name:='Unknown '+chp+' chip ('+istr(id)+')';
end;
(* Tests for various adapters *)
function _chipstech:boolean;
begin
_chipstech:=false;
if dotest[__CHIPS451] then
begin
vio($5f00);
if rp.al=$5f then
begin
_chipstech:=true;
case rp.bl shr 4 of
0:name:='Chips & Tech 82c451';
1:name:='Chips & Tech 82c452';
2:name:='Chips & Tech 82c455';
3:name:='Chips & Tech 82c453';
5:name:='Chips & Tech 82c456';
6:name:='Chips & Tech 82c457';
7:name:='Chips & Tech F65520';
8:name:='Chips & Tech F65530';
else UNK('Chips & Tech',rp.bl shr 4);
end;
case rp.bl shr 4 of
1:CHIP:=__chips452;
3:CHIP:=__chips453;
else chip:=__chips451;
end;
case rp.bh of
1:mm:=512;
2:mm:=1024;
end;
end;
end;
end;
function _paradise:boolean;
var old,old1,old2:word;
begin
_paradise:=false;
if dotest[__PARADISE] then
begin
old:=rdinx($3ce,15);
modinx($3ce,15,$17,0); {Lock registers}
if not testinx2($3ce,9,$7f) then
begin
wrinx($3ce,15,5); {Unlock them again}
if testinx2($3ce,9,$7f) then
begin
_paradise:=true;
old2:=rdinx(crtc,$29);
name:='Paradise ';
modinx(crtc,$29,$8f,$85); {Unlock WD90Cxx registers}
if not testinx(crtc,$2b) then name:=name+'PVGA1A'
else begin
old1:=rdinx($3c4,6);
wrinx($3c4,6,$48);
if not testinx2($3c4,7,$f0) then name:=name+'WD90C00'
else if not testinx($3c4,16) then
begin
name:=name+'WD90C2x';
wrinx(crtc,$34,$a6);
if (rdinx(crtc,$32) and 32)<>0 then wrinx(crtc,$34,0);
end
else if testinx2($3c4,20,15) then
begin
if rdinx(crtc,$37)=$31 then name:=name+'WD90C31'
else name:=name+'WD90C30';
end
else if not testinx2($3c4,16,4) then name:=name+'WD90C10'
else name:=name+'WD90C11';
wrinx($3c4,6,old1);
end;
case rdinx($3ce,11) shr 6 of
2:mm:=512;
3:mm:=1024;
end;
wrinx(crtc,$29,old2);
chip:=__paradise;
end;
end;
wrinx($3ce,15,old);
end;
end;
function _video7:boolean;
begin
_video7:=false;
if dotest[__video7] then
begin
vio($6f00);
if rp.bx=$5637 then
begin
_video7:=true;
vio($6f07);
case rp.bl of
$80..$ff:name:='Video7 VEGA VGA';
$70..$7f:name:='Video7 FASTWRITE/VRAM';
$50..$5f:name:='Video7 Version 5';
$41..$4f:name:='Video7 1024i';
end;
case rp.ah and 127 of
2:mm:=512;
4:mm:=1024;
end;
chip:=__video7;
end
end;
end;
function _genoa:boolean;
var ad:word;
begin
_genoa:=false;
if dotest[__genoa] then
begin
ad:=memw[biosseg:$37];
if (memw[biosseg:ad+2]=$6699) and (mem[biosseg:ad]=$77) then
begin
_genoa:=true;
case mem[biosseg:ad+1] of
0:name:='Genoa 62/300';
$11:begin
name:='Genoa 64/500';
mm:=512;
end;
$22:name:='Genoa 6100';
$33:name:='Genoa 51/5200 (Tseng 3000)';
$55:begin
name:='Genoa 53/5400 (Tseng 3000)';
mm:=512;
end;
end;
if mem[biosseg:ad+1]<$33 then chip:=__genoa else chip:=__tseng3;
end
end;
end;
function _tseng:boolean;
var x,vs:word;
begin
_tseng:=false;
if dotest[__TSENG3] or dotest[__TSENG4] then
begin
outp($3bf,3);
outp($3d8,$a0); {Enable Tseng 4000 extensions}
if tstrg($3cd,$3f) then
begin
_tseng:=true;
if testinx2(crtc,$33,$f) then
begin
name:='Tseng ET4000';
case rdinx(crtc,$37) and 11 of
3,9:mm:=256;
10:mm:=512;
11:mm:=1024;
end;
(* vio($10f1);
if (rp.ax=$10) then
case rp.bl of
1:name:=name+' /w Sierra RAMDAC';
2:name:=name+' /w SS24 RAMDAC';
end; *)
chip:=__tseng4;
end
else begin
name:='Tseng ET3000';
chip:=__tseng3;
if setmode($13) then;
x:=port[$3da];
x:=rdinx($3c0,$36);
port[$3c0]:=x or 16;
case (rdinx($3ce,6) shr 2) and 3 of
0,1:vs:=$a000;
2:vs:=$b000;
3:vs:=$b800;
end;
meml[vs:1]:=$12345678;
if memw[vs:2]=$3456 then mm:=512;
wrinx($3c0,$36,x); {reset value and reenable DAC}
end;
end;
end;
end;
function _trident:boolean;
var chp,old,val:word;
begin
_trident:=false;
if dotest[__tridBR] or dotest[__trid89] or dotest[__tridCS] then
begin
wrinx($3c4,11,0);
chp:=inp($3c5);
old:=rdinx($3c4,14);
outp($3c5,0);
val:=inp($3c5);
outp($3c5,old);
if (val and 15)=2 then
begin
_trident:=true;
case chp of
1:name:='Trident 8800BR';
2:name:='Trident 8800CS';
3:name:='Trident 8900';
4:name:='Trident 8900C';
$13:name:='Trident 8900C';
$23:name:='Trident 9000';
$83:name:='Trident LX9200';
$93:name:='Trident LCD9100';
else UNK('Trident',chp);
end;
case chp and 15 of
1:chip:=__tridbr;
2:chip:=__tridCS;
3:chip:=__trid89;
end;
if (pos('Zymos Poach 51',getbios(0,255))>0) or
(pos('Zymos Poach 51',getbios(230,255))>0) then
begin
name:=name+' (Zymos Poach)';
chip:=__poach;
end;
if (chp>=3) then
begin
case rdinx(crtc,$1f) and 3 of
0:mm:=256;
1:mm:=512;
2:mm:=768;
3:mm:=1024;
end;
end
else
if (rdinx(crtc,$1f) and 2)>0 then mm:=512;
end;
end;
end;
function _oak:boolean;
begin
_oak:=false;
if dotest[__oak] then
begin
if testinx2($3de,$d,$38) then
begin
_oak:=true;
name:='OAK 037C';
if testinx($3DE,$11) then
begin
if rdinx($3DE,$B)=5 then name:='OAK 077'
else name:='OAK 067';
end;
case rdinx($3de,13) shr 6 of
2:mm:=512;
1,3:mm:=1024; {1 might not give 1M??}
end;
chip:=__oak;
end;
end;
end;
function _cirrus:boolean;
var old,eagle:word;
begin
_cirrus:=false;
if dotest[__cirrus] then
begin
old:=rdinx(crtc,12);
outp(crtc+1,0);
eagle:=rdinx(crtc,$1f);
wrinx($3c4,6,lo(eagle shr 4) or lo(eagle shl 4));
if inp($3c5)=0 then
begin
outp($3c5,eagle);
if inp($3c5)=1 then
begin
_cirrus:=true;
case eagle of
$EC:name:='Cirrus 510/520';
$CA:name:='Cirrus 610/620';
$EA:name:='Cirrus Video 7 OEM'
else UNK('Cirrus',eagle);
end;
chip:=__cirrus;
end;
end;
wrinx(crtc,12,old);
end;
end;
function _cirrus54:boolean;
var x,old:word;
begin
_cirrus54:=false;
if dotest[__cirrus54] then
begin
old:=rdinx($3C4,6);
wrinx($3c4,6,$12);
if (rdinx($3C4,6)=$12) and testinx2($3C4,$1E,$3F) and testinx2(crtc,$1B,$ff) then
begin
x:=rdinx(crtc,$27);
case x of
$8A:name:='Cirrus 54xx typ 2';
$8C..$8F:name:='Cirrus 54xx typ 3';
$90..$93:name:='Cirrus 54xx typ 5';
$94..$97:name:='Cirrus 54xx typ 4';
else UNK('Cirrus54',x);
end;
case rdinx($3C4,$F) and $18 of
0:mm:=0;
8:mm:=512;
16:mm:=1024;
end;
_cirrus54:=true;
chip:=__cirrus54;
end
else wrinx($3C4,6,old);
end;
end;
function _ahead:boolean;
var old:word;
begin
_ahead:=false;
if dotest[__aheadA] or dotest[__aheadB] then
begin
old:=rdinx($3ce,15);
wrinx($3ce,15,0);
if not testinx2($3ce,12,$FB) then
begin
wrinx($3ce,15,$20);
if testinx2($3ce,12,$FB) then
begin
_ahead:=true;
case rdinx($3ce,15) and 15 of
0:begin
name:='Ahead A';
chip:=__aheadA;
end;
1:begin
name:='Ahead B';
chip:=__aheadB;
end;
end;
end;
end;
wrinx($3ce,15,old);
end;
end;
function _everex:boolean;
var x:word;
begin
_everex:=false;
if dotest[__everex] then
begin
rp.bx:=0;
vio($7000);
if rp.al=$70 then
begin
x:=rp.dx shr 4;
if (x<>$678) and (x<>$236)
and (x<>$620) and (x<>$673) then {Some Everex boards use Trident chips.}
begin
_everex:=true;
case rp.ch shr 6 of
0:mm:=256;
1:mm:=512;
2:mm:=1024;
3:mm:=2048;
end;
name:='Everex Ev'+hx[x shr 8]+hx[(x shr 4) and 15]+hx[x and 15];
chip:=__everex;
end;
end;
end;
end;
function _ati:boolean;
var w:word;
begin
_ati:=false;
if dotest[__ATI1] or dotest[__ati2] then
begin
if getbios($31,9)='761295520' then
begin
_ati:=true;
case memw[biosseg:$40] of
$3133:begin
atireg:=memw[biosseg:$10];
name:='ATI VGA Wonder';
w:=rdinx(atireg,$bb);
case w and 15 of
0:_crt:='EGA';
1:_crt:='Analog Monochrome';
2:_crt:='Monochrome';
3:_crt:='Analog Color';
4:_crt:='CGA';
6:_crt:='';
7:_crt:='IBM 8514/A';
else _crt:='Multisync';
end;
chip:=__ati2;
case chr(mem[biosseg:$43]) of
'1':begin
name:=name+' (18800)';
chip:=__ati1;
end;
'2':name:=name+' (18800-1)';
'3':name:=name+' (28800-2)';
'4':name:=name+' (28800-4)';
'5':begin
name:=name+' (28800-5)';
if (mem[biosseg:$44] and 128)<>0 then
name:=name+' /w HICOLOR DAC';
end;
end;
case chr(mem[biosseg:$43]) of
'1','2':if (rdinx(atireg,$bb) and 32)<>0 then mm:=512;
'3':if (rdinx(atireg,$b0) and 16)<>0 then mm:=512;
'4','5':case rdinx(atireg,$b0) and $18 of
0:mm:=256;
$10:mm:=512;
8,$18:mm:=1024;
end;
end;
end;
$3233:begin
name:='ATI EGA Wonder';
video:='EGA';
chip:=__ega;
end;
end;
end;
end;
end;
function _s3:boolean;
var x:word;
begin
_s3:=false;
if dotest[__s3] then
begin
wrinx(crtc,$38,0);
if not testinx2(crtc,$35,$f) then
begin
wrinx(crtc,$38,$48);
if testinx2(crtc,$35,$f) then
begin
_s3:=true;
chip:=__s3;
x:=rdinx(crtc,$30);
case x of
$81:name:='S3 86c911';
$82:name:='S3 86c911A'; {Whats the diff?}
else UNK('S3',x);
end;
if (rdinx(crtc,$41) and $10)<>0 then mm:=1024
else mm:=512;
end;
end;
end;
end;
function _al2101:boolean;
begin
_al2101:=false;
if dotest[__al2101] then
begin
if tstrg($8286,$ff) and testinx2(crtc,$1f,$3b)
and testinx2($3ce,13,15) then
begin
_al2101:=true;
name:='Avance Logic 2101';
chip:=__al2101;
case rdinx(crtc,$1e) and 3 of
0:mm:=256;
1:mm:=512;
2:mm:=1024;
3:mm:=2048;
end;
end;
end;
end;
function _vesa:boolean;
begin
_vesa:=false;
if dotest[__vesa] then
begin
vio($4f03);
if rp.al=$4f then
begin
_vesa:=true;
name:='VESA';
chip:=__vesa;
vesa:=1;
end;
end;
end;
function _yamaha:boolean;
begin
_yamaha:=false;
if dotest[__yamaha] then
begin
if testinx2($3d4,$7c,$7c) then
begin
_yamaha:=true;
name:='Yamaha 6388'
end;
end;
end;
function _ncr:boolean;
var x:word;
begin
_ncr:=false;
if dotest[__ncr] then
begin
if testinx2($3c4,5,5) then
begin
wrinx($3c4,5,0); {Disable extended registers}
if not testinx2($3c4,16,$ff) then
begin
wrinx($3c4,5,1); {Enable extended registers}
if testinx2($3c4,16,$ff) then
begin
_ncr:=true;
chip:=__ncr;
x:=rdinx($3c4,8) shr 4;
case x of
0:name:='NCR 77C22';
1:name:='NCR 77C21';
2:name:='NCR 77C22E';
8..15:name:='NCR 77C22E+';
else UNK('NCR',x);
end;
name:=name+' Rev. '+istr(rdinx($3c4,8) and 15);
if setmode($13) then;
checkmem(64);
end;
end;
end;
end;
end;
function _acumos:boolean;
var old:word;
begin
_acumos:=false;
if dotest[__acumos] then
begin
old:=rdinx($3c4,6);
{ wrinx($3c4,6,0);
if not testinx2($3ce,9,$f0) then }
begin
wrinx($3c4,6,$12);
if testinx2($3ce,9,$30) then
begin
_acumos:=true;
name:='Acumos AVGA2';
chip:=__acumos;
case rdinx($3c4,$a) and 3 of
0:mm:=256;
1:mm:=512;
2:mm:=1024;
end;
end;
end;
wrinx($3c4,6,old);
end;
end;
function _mxic:boolean;
begin
_mxic:=false;
if dotest[__mxic] then
begin
old:=rdinx($3c4,$a7);
wrinx($3c4,$a7,0); {disable extensions}
if not testinx($3c4,$c5) then
begin
wrinx($3c4,$a7,$87); {enable extensions}
if testinx($3c4,$c5) then
begin
_mxic:=true;
chip:=__mxic;
name:='MX 86010';
case (rdinx($3c4,$c2) shr 2) and 3 of
0:mm:=256;
1:mm:=512;
2:mm:=1024;
end;
end;
end;
wrinx($3c4,$a7,old);
end;
end;
function _p2000:boolean;
begin
_p2000:=false;
if dotest[__p2000] then
begin
if testinx2($3CE,$3d,$3f) and tstrg($3d6,$1f) and tstrg($3d7,$1f) then
begin
_p2000:=true;
name:='Primus P2000';
chip:=__p2000;
if setmode($13) then;
checkmem(32);
end;
end;
end;
function _realtek:boolean;
var x:word;
begin
_realtek:=false;
if dotest[__realtek] then
begin
if testinx2(crtc,$1f,$3f) and tstrg($3d6,$f) and tstrg($3d7,$f) then
begin
chip:=__realtek;
name:='Realtek';
_realtek:=true;
x:=rdinx(crtc,$1a) shr 6;
case x of
0..2:name:='Realtek version '+istr(x);
else UNK('Realtek',x);
end;
case rdinx(crtc,$1e) and 15 of
0:mm:=256;
1:mm:=512;
2:if x=0 then mm:=768 else mm:=1024;
3:if x=0 then mm:=1024 else mm:=2048;
end;
end;
end;
end;
function testdac:string; {Test for type of DAC}
var
x,y,z,v,oldcommreg,oldpelreg:word;
begin
IF chip=__al2101 then (* Special case -- weird DAC *)
begin
dactype:=_dac16;
testdac:='AVL DAC 16';
exit;
end;
testdac:='Normal';
dactype:=_dac8;
dactopel;
x:=inp($3c6);
repeat
y:=x; {wait for the same value twice}
x:=inp($3c6);
until (x=y);
z:=x;
dactocomm;
if daccomm<>$8e then
begin {If command register=$8e, we've got an SS24}
y:=8;
repeat
x:=inp($3c6);
dec(y);
until (x=$8e) or (y=0);
end
else x:=daccomm;
if x=$8e then
begin
dactype:=_dacss24;
testdac:='SS24';
dactopel;
end
else begin
dactocomm;
oldcommreg:=inp($3c6);
dactopel;
oldpelreg:=inp($3c6);
x:=oldcommreg xor 255;
outp($3c6,x);
dactocomm;
v:=inp($3c6);
if v<>x then
begin
dactocomm;
x:=oldcommreg xor $60;
outp($3c6,x);
dactocomm;
v:=inp($3c6);
testdac:='Sierra SC11486';
dactype:=_dac15;
if (x and $e0)=(v and $e0) then
begin
x:=inp($3c6);
dactopel;
testdac:='Sierra 32k/64k';
dactype:=_dac15; (* Can't tell the difference *)
if x=inp($3c6) then
begin
testdac:='ATT 20c491/2';
dactype:=_dacatt;
dactocomm;
outp($3c6,255);
dactocomm;
x:=inp($3c6);
if x<>255 then
begin
testdac:='Acumos ADAC';
dactype:=_dacadac1;
end;
end;
end;
dactocomm;
outp($3c6,oldcommreg);
end;
dactopel;
outp($3c6,oldpelreg);
end;
end;
procedure findbios; {Finds the most likely BIOS segment}
var
score:array[0..7] of byte;
x,y:word;
begin
biosseg:=$c000;
for x:=0 to 6 do score[x]:=1;
for x:=0 to 7 do
begin
rp.bh:=x;
vio($1130);
if (rp.es>=$c000) and ((rp.es and $7ff)=0) then
inc(score[(rp.es-$c000) shr 11]);
end;
for x:=0 to 6 do
begin
y:=$c000+(x shl 11);
if (memw[y:0]<>$aa55) or (mem[y:2]<48) then
score[x]:=0; {fail if no rom}
end;
for x:=6 downto 0 do
if score[x]>0 then
biosseg:=$c000+(x shl 11);
end;
procedure findvideo;
begin
dactype:=_dac0;
extra:='';
_crt:='';
chip:=__none;
secondary:='';
name:='';
video:='none';
rp.ah:=18;
rp.bx:=$1010;
intr(16,rp);
if rp.bh<=1 then
begin
video:='EGA';
chip:=__ega;
if odd(inp($3cc)) then crtc:=$3d4
else crtc:=$3b4;
mm:=rp.bl;
vio($1a00);
if rp.al=$1a then
begin
if (rp.bl<4) and (rp.bh>3) then
begin
old:=rp.bl;
rp.bl:=rp.bh;
rp.bh:=old;
end;
video:='MCGA';
case rp.bl of
2,4,6,10:_crt:='TTL Color';
1,5,7,11:_crt:='Monochrome';
8,12:_crt:='Analog Color';
end;
case rp.bh of
1:secondary:='Monochrome';
2:secondary:='CGA';
end;
findbios;
if (getbios($31,9)='') and (getbios($40,2)='22') then
begin
video:='EGA'; {@#%@ lying ATI EGA Wonder !}
name:='ATI EGA Wonder';
end else
if (rp.bl<10) or (rp.bl>12) then
begin
video:='VGA';
chip:=__vga;
mm:=256;
if _vesa then extra:=extra+'VESA ';
if _chipstech then
else if _paradise then
else if _video7 then
else if _genoa then
else if _everex then
else if _trident then
else if _ati then
else if _ahead then
else if _ncr then
else if _s3 then
else if _al2101 then
else if _mxic then
else if _cirrus54 then
else if _acumos then
else if _tseng then
else if _realtek then
else if _p2000 then
else if _yamaha then
else if _oak then
else if _cirrus then;
dacname:=testdac;
end;
end;
end;
end;
begin
end.